/*
 * Copyright (c) 2007 Compl Yue Still, All Rights Reserved.
 */

package hbi.wire.as3.host
{
	import flash.utils.IDataInput;
	
	import hbi.task.as3.TaskAgentLifeScript;
	import hbi.wire.ProtocolError;

	public class TaskScript implements IncomingTag
	{
		private var hostEnd:HostEnd;
		
		public function TaskScript(hostEnd:HostEnd)
		{
			this.hostEnd = hostEnd;
		}
		
		internal var agentType:ResolvedType = null;
		
		[ArrayElementType("hbi.task.as3::AgentMethodInvocation")]
		internal const invocations:Array = new Array();
		
		private var incomingTag:IncomingTag = null;
		
		public function processIncomingData(input:IDataInput):Boolean
		{
			tag_scan: while(input.bytesAvailable > 0)
			{
				if(incomingTag == null)
				{
					if(agentType == null)
					{
						if(input.bytesAvailable < 4) return false;
						var typeIndex:int = input.readInt();
						if(typeIndex < 0) throw new ProtocolError("Too big index.");
						agentType = hostEnd.getResolvedType(typeIndex);
						if(input.bytesAvailable < 1) break tag_scan;
					}
					var tag:uint = input.readUnsignedByte();
					switch (tag)
					{
					case 'c'.charCodeAt(): // scripted method invocation
						incomingTag = new MethodInvocation(this);
						break;
					case 'm'.charCodeAt(): // method constant
						incomingTag = new MethodConstant(this.agentType);
						break;
					case 'H'.charCodeAt(): // meta header
						throw new Error("Meta Header not implemented yet.");
					case 'z'.charCodeAt(): // end of life script
						hostEnd.hostTaskAgent(new TaskAgentLifeScript(
							agentType.as3Class, invocations));
						return true;
					default:
						throw new ProtocolError("Bad agent tag: " + tag);
					}
				}
				if (incomingTag.processIncomingData(input))
					incomingTag = null;
				else
					break tag_scan;
			}
			
			return false;
		}
		
	}
}
